#include "StdAfx.h"
#include ".\cmpp20stream.h"

CCMPP30Stream::CCMPP30Stream(void)
{
	
}

CCMPP30Stream::~CCMPP30Stream(void)
{
	sock.Close();
}

bool CCMPP30Stream::Connect(string server, int port, Cmpp_Connect* pack)
{
	sock.Close();
	sock.Create();
	if (!sock.Connect(server.c_str(), port)) return false;
	if (!Write(pack)) return false;
	Cmpp_Base * ret = Read();
	if (ret == NULL) return false;
	if (ret->type == "connect_resp") {
		if (((Cmpp_Connect_Resp*)ret)->Status == 0) {
			delete ret;
			return true;
		} else {
			delete ret;
			return false;
		}
	} else {
		delete ret;
		return false;
	}
}

bool CCMPP30Stream::Write(Cmpp_Base * pack)
{
	if (pack != NULL) {
	    cstring encode;
		pack->encode(&encode);
		string str;
		encode.getString(str);
		return Write(str);
	} else {
		return false;
	}
}

bool CCMPP30Stream::Write(string s) {
	char *ptr,*ptr1;
	int nleft,n;
	int nwrite;
	nleft = s.size();
	n = nleft;
	ptr1 = new char[nleft+1];
	ptr =ptr1;
	memcpy(ptr, s.c_str(), n);
	while(nleft>0) {
		nwrite= sock.Send(ptr, nleft);
		if(nwrite<1) {
			delete []ptr1;
			return false;
		}
		nleft = nleft - nwrite;
		ptr += nwrite;
	}
	delete []ptr1;
	return nleft==0?true:false;
}

bool CCMPP30Stream::Read(string& s, size_t n)
{
	char buf [ 500 + 1 ];

	s = "";
	size_t nleft, nsread;
	int nread;
	nleft = n;
	while (nleft>0) {
		nsread = nleft<500?nleft:500;
		memset ( buf, 0, nsread );
		if ((nread = sock.Receive(buf, nsread)) < 1) {
			return false;
		}
		nleft = nleft - nread;
		s.append(buf, nread);
	}
	return true;
}

Cmpp_Base * CCMPP30Stream::Read(void)
{
    string strHead;
	unsigned int messLen;
    if (Read(strHead, 8)) {
		Cmpp_Base *cmppbase;
		cmppbase = Cmpp_Base::getInstance(strHead, messLen);
		if (cmppbase) {
			string strBody;
			if (Read(strBody, messLen - 8)) {
				cstring cstr;
				cstr.appendString(strHead);
				cstr.appendString(strBody);
				cmppbase->decode(&cstr);
				return cmppbase;
			} else delete cmppbase;
		}
	}
	return NULL;
}

void CCMPP30Stream::Terminate(Cmpp_Terminate * pack)
{
	Write(pack);
	sock.Close();
}
